package cn.edu.jsu.official.dao.daoImpl;

import cn.edu.jsu.official.dao.AdminDao;
import cn.edu.jsu.official.pojo.dto.*;
import cn.edu.jsu.official.pojo.vo.*;
import cn.edu.jsu.official.utils.FileUtil;
import com.mongodb.client.result.UpdateResult;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;

import java.util.*;

/**
 * @author Mo
 * @createTime 2022/3/2 23:11
 * @description
 */
@Repository
public class AdminDaoImpl implements AdminDao {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private GridFsTemplate gridFsTemplate;

    @Override
    public Integer queryAccount(String userAccount) {
        UserInfo userInfo = mongoTemplate.findById(userAccount, UserInfo.class);
        if (userInfo != null) {
            return 1;
        } else {
            return 0;
        }
    }

    @Override
    public UserInfo queryAccountInfo(LoginVO loginVO) {
        Query query = new Query(Criteria.where("_id").is(loginVO.getUserAccount()).and("password").is(loginVO.getUserPassword()));
        UserInfo userInfo = mongoTemplate.findOne(query, UserInfo.class);
        return userInfo;
    }

    @Override
    public ObjectId uploadFile(MultipartFile multipartFile) {
        InputStream inputStream = null;
        String fileName = multipartFile.getOriginalFilename();
        String fileContentType = multipartFile.getContentType();
        ObjectId objectId = null;
        try {
            inputStream = multipartFile.getInputStream();
            objectId = gridFsTemplate.store(inputStream, fileName, fileContentType);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return objectId;
    }

    @Override
    public void deleteFile(Map<String, ObjectId> map) {
        List<ObjectId> objectIdList = new ArrayList<>();
        for (ObjectId value : map.values()) {
            objectIdList.add(value);
        }
        Query query = new Query(Criteria.where("_id").in(objectIdList));
        gridFsTemplate.delete(query);
    }

    @Override
    public ArticleVO insertArticle(ArticleVO articleVO) {
        ArticleVO articleVO1 = mongoTemplate.save(articleVO);
        return articleVO1;
    }

    @Override
    public void addProjectAchievement(ProjectAchievement projectAchievement) {
        ProjectAchievement save = mongoTemplate.save(projectAchievement);
        System.out.println(save);
    }

    @Override
    public List<Map<String, ObjectId>> deleteProjectAchievementList(List<String> projectAchievementIdList) {
        Query query = new Query(Criteria.where("_id").in(projectAchievementIdList));
        List<ProjectAchievement> achievementList = mongoTemplate.findAllAndRemove(query, ProjectAchievement.class);
        List<Map<String, ObjectId>> mapList = new ArrayList<>();
        for (ProjectAchievement projectAchievement : achievementList) {
            Query queryArticle = new Query(Criteria.where("_id").is(projectAchievement.getArticleId()));
            ArticleVO articleVO = mongoTemplate.findAndRemove(queryArticle, ArticleVO.class);
            System.out.println(articleVO.getResourcesPath());
            if (articleVO != null) {
                FileUtil.deleteDirectory(articleVO.getResourcesPath());
            } else {
                System.out.println("articleVO为null");
            }
            Map<String, ObjectId> map = new HashMap<String, ObjectId>();
            map.put("frontCoverId", projectAchievement.getFrontCoverId());
            mapList.add(map);
        }
        return mapList;
    }


    @Override
    public void addContestAchievement(ContestAchievement contestAchievement) {
        ContestAchievement save = mongoTemplate.save(contestAchievement);
        System.out.println(save);
    }

    @Override
    public List<Map<String, ObjectId>> deleteContestAchievementList(List<String> contestAchievementIdList) {
        Query query = new Query(Criteria.where("_id").in(contestAchievementIdList));
        List<ContestAchievement> contestAchievementList = mongoTemplate.findAllAndRemove(query, ContestAchievement.class);
        List<Map<String, ObjectId>> mapList = new ArrayList<>();
        for (ContestAchievement contestAchievement : contestAchievementList) {
            System.out.println(contestAchievement);
            Query queryArticle = new Query(Criteria.where("_id").is(contestAchievement.getArticleId()));
            ArticleVO articleVO = mongoTemplate.findAndRemove(queryArticle, ArticleVO.class);
            if (articleVO != null) {
                FileUtil.deleteDirectory(articleVO.getResourcesPath());
            } else {
                System.out.println("articleVO为null");
            }
            Map<String, ObjectId> map = new HashMap<>();
            map.put("frontCoverId", contestAchievement.getFrontCoverId());
            mapList.add(map);
        }
        return mapList;
    }

    @Override
    public void addGoalInfo(GoalInfo goalInfo) {
        GoalInfo goalInfo1 = mongoTemplate.insert(goalInfo);
        System.out.println(goalInfo1);
    }

    @Override
    public void addMemberInfo(MemberInfo memberInfo) {
        mongoTemplate.insert(memberInfo);
    }

    @Override
    public void addProjectInProgress(ProjectInProgressInfo projectInProgressInfo) {
        ProjectInProgressInfo insert = mongoTemplate.insert(projectInProgressInfo);
        System.out.println(insert);
    }

    @Override
    public void addContestInfo(ContestInfo contestInfo) {
        ContestInfo insert = mongoTemplate.insert(contestInfo);
        System.out.println(insert);

    }

    @Override
    public void uploadCopyright(CopyrightInfo copyrightInfo) {
        CopyrightInfo insert = mongoTemplate.insert(copyrightInfo);
        System.out.println(insert);
    }


    @Override
    public void deleteProjectInProgress(List<String> projectIdList) {
        Query query = new Query(Criteria.where("_id").in(projectIdList));
        List<ProjectInProgressInfo> list = mongoTemplate.findAllAndRemove(query, ProjectInProgressInfo.class);
        list.forEach(System.out::println);
    }

    @Override
    public List<Map<String, ObjectId>> deleteMemberIdList(List<String> memberIdList) {
        Query query = new Query(Criteria.where("_id").in(memberIdList));
        List<MemberInfo> list = mongoTemplate.findAllAndRemove(query, MemberInfo.class);
        List<Map<String, ObjectId>> mapList = new ArrayList<>();
        for (MemberInfo memberInfo : list) {
            Map<String, ObjectId> map = new HashMap<>();
            map.put("memberImageId", memberInfo.getMemberImageId());
        }
        return mapList;
    }

    @Override
    public List<Map<String, ObjectId>> deleteContestInfoList(List<String> contestInfoIdList) {
        Query query=new Query(Criteria.where("_id").in(contestInfoIdList));
        List<ContestInfo> contestInfosList=mongoTemplate.findAllAndRemove(query,ContestInfo.class);
        List<Map<String,ObjectId>> mapList=new ArrayList<>();
        for(ContestInfo contestInfo:contestInfosList){
            System.out.println(contestInfo);
            Map<String,ObjectId>map=new HashMap<>();
            map.put("contestImageId",contestInfo.getContestImageId());
            mapList.add(map);
        }
        return mapList;
    }

    @Override
    public void deleteGoalInfo(List<String> goalIdList) {
        Query query = new Query(Criteria.where("_id").in(goalIdList));
        List<GoalInfo> list = mongoTemplate.findAllAndRemove(query, GoalInfo.class);
        list.forEach(System.out::println);
    }
    @Override
    public List<Map<String, ObjectId>> deleteCopyrightList(List<String> copyrightIdList) {
        Query query=new Query(Criteria.where("_id").in(copyrightIdList));
        List<CopyrightInfo> copyrightInfoList=mongoTemplate.findAllAndRemove(query,CopyrightInfo.class);
        List<Map<String,ObjectId>> mapList=new ArrayList<>();
        for(CopyrightInfo copyrightInfo:copyrightInfoList){
            System.out.println(copyrightInfo);
            Map<String,ObjectId> map = new HashMap<>();
            Query queryArticle = new Query(Criteria.where("_id").is(copyrightInfo.getArticleId()));
            ArticleVO articleVO = mongoTemplate.findAndRemove(queryArticle, ArticleVO.class);
            if (articleVO != null) {
                FileUtil.deleteDirectory(articleVO.getResourcesPath());
            } else {
                System.out.println("articleVO为null");
            }
            map.put("articleId",copyrightInfo.getArticleId());
            mapList.add(map);
        }
        return mapList;
    }

    @Override
    public long countMember() {
        Query query = new Query();
        long memberNumber = mongoTemplate.count(query, MemberInfo.class);
        return memberNumber;
    }

    @Override
    public long countCopyright() {
        Query query = new Query();
        long count = mongoTemplate.count(query, CopyrightInfo.class);
        return count;
    }

    @Override
    public long countContestAchievement() {
        Query query = new Query();
        long count = mongoTemplate.count(query, ContestAchievement.class);
        return count;
    }

    @Override
    public long countProjectAchievement() {
        Query query = new Query();
        long count = mongoTemplate.count(query, ProjectAchievement.class);
        return count;
    }

    @Override
    public long updateHistoryProcess(HistoryProcess historyProcess) {
        Query query = Query.query(Criteria.where("_id").is(historyProcess.getHistoryProcessId()));
        Update update = new Update();
        update.set("event",historyProcess.getEvent());
        update.set("event_date",historyProcess.getEventDate());
        return mongoTemplate.updateFirst(query,update, HistoryProcess.class).getMatchedCount();
    }

    @Override
    public long updateProjectAchievement(ProjectAchievement projectAchievement) {
        Query query = Query.query(Criteria.where("_id").is(projectAchievement.getProjectAchievementId()));
        Update update = new Update();
        update.set("project_member",projectAchievement.getProjectMember());
        update.set("project_name",projectAchievement.getProjectName());
        update.set("project_introduction",projectAchievement.getProjectIntroduction());
        update.set("completed_date",projectAchievement.getCompletedDate());
        return mongoTemplate.updateFirst(query,update, ProjectAchievement.class).getMatchedCount();
    }

    @Override
    public long updateContestInfo(ContestInfo contestInfo) {
        Query query = Query.query(Criteria.where("_id").is(contestInfo.getContestInfoId()));
        Update update = new Update();
        update.set("contest_name",contestInfo.getContestName());
        update.set("contest_introduction",contestInfo.getContestIntroduction());
        update.set("start_time",contestInfo.getStartTime());
        update.set("contest_participants",contestInfo.getContestParticipants());
        return mongoTemplate.updateFirst(query,update, ContestInfo.class).getMatchedCount();
    }

    @Override
    public long updateGoalInfo(GoalInfo goalInfo) {
        Query query = Query.query(Criteria.where("_id").is(goalInfo.getGoalId()));
        Update update = new Update();
        update.set("goal_name",goalInfo.getGoalName());
        update.set("date",goalInfo.getDate());
        update.set("steps",goalInfo.getSteps());
        return mongoTemplate.updateFirst(query,update, GoalInfo.class).getMatchedCount();
    }

    @Override
    public void addHistoryProcess(HistoryProcess historyProcess) {
        HistoryProcess save = mongoTemplate.save(historyProcess);
        System.out.println(save);
    }

    @Override
    public void deleteHistoryProcess(List<String> historyProcessIdList) {
        Query query = new Query(Criteria.where("_id").in(historyProcessIdList));
        List<HistoryProcess> list = mongoTemplate.findAllAndRemove(query, HistoryProcess.class);
        System.out.println("已删除: ");
        for (HistoryProcess historyProcess : list) {
            System.out.println(historyProcess);
        }
    }

    @Override
    public int updateProjectInProgress(ProjectInProgressInfo projectInProgressInfo) {
        Query query = new Query(Criteria.where("_id").is(projectInProgressInfo.getProjectInProgressInfoId()));
        List<ProjectInProgressInfo> list = mongoTemplate.find(query, ProjectInProgressInfo.class);
        if (list.size() == 0) {
            return 0;
        }
        Update update = Update.update("projectName", projectInProgressInfo.getProjectName());
        update.set("projectIntroduction", projectInProgressInfo.getProjectIntroduction());
        update.set("projectParticipants", projectInProgressInfo.getProjectParticipants());
        update.set("projectStartDate", projectInProgressInfo.getProjectStartDate());
        UpdateResult first = mongoTemplate.update(ProjectInProgressInfo.class)
                .matching(query)
                .apply(update)
                .first();
        System.out.println(first);
        return 1;
    }

    @Override
    public int updateContestAchievement(ContestAchievement contestAchievement) {
        Query query = new Query(Criteria.where("_id").is(contestAchievement.getContestAchievementId()));
        List<ContestAchievement> contestAchievements = mongoTemplate.find(query, ContestAchievement.class);
        if (contestAchievements.size() != 1) {
            return 0;
        }
        Update update = new Update();
        update.set("contestName", contestAchievement.getContestName());
        update.set("contestResult", contestAchievement.getContestResult());
        update.set("contestIntroduction", contestAchievement.getContestIntroduction());
        update.set("contestParticipants", contestAchievement.getContestParticipants());
        update.set("completedDate", contestAchievement.getCompletedDate());
        UpdateResult first = mongoTemplate.update(ContestAchievement.class)
                .matching(query)
                .apply(update)
                .first();
        System.out.println(first);
        return 1;
    }

    @Override
    public int updateCopyright(CopyrightInfo copyrightInfo) {
        Query query = new Query(Criteria.where("_id").is(copyrightInfo.getCopyrightId()));
        List<CopyrightInfo> copyrightInfos = mongoTemplate.find(query, CopyrightInfo.class);
        if (copyrightInfos.size() != 1) {
            return 0;
        }
        Update update = new Update();
        update.set("copyrightName", copyrightInfo.getCopyrightName());
        update.set("copyrightAuthors", copyrightInfo.getCopyrightAuthors());
        update.set("copyrightIntroduction", copyrightInfo.getCopyrightIntroduction());
        update.set("completedDate", copyrightInfo.getCompletedDate());
        UpdateResult first = mongoTemplate.update(CopyrightInfo.class)
                .matching(query)
                .apply(update)
                .first();
        System.out.println(first);
        return 1;
    }

    @Override
    public int updateMemberInfo(MemberInfo memberInfo) {
        Query query = new Query(Criteria.where("_id").is(memberInfo.getMemberId()));
        List<MemberInfo> memberInfos = mongoTemplate.find(query, MemberInfo.class);
        if (memberInfos.size() != 1) {
            return 0;
        }
        Update update = new Update();
        update.set("memberName", memberInfo.getMemberName());
        update.set("department", memberInfo.getDepartment());
        update.set("major", memberInfo.getMajor());
        update.set("isActive", memberInfo.getIsActive());
        update.set("memberIntroduction", memberInfo.getMemberIntroduction());
        update.set("isGraduated", memberInfo.getIsGraduated());
        if (memberInfo.getIsGraduated() == 1) {
            update.set("graduationDestination", memberInfo.getGraduationDestination());
        } else {
            update.set("graduationDestination", null);
        }
        update.set("personalTechStack", memberInfo.getPersonalTechStack());
        update.set("personalAchievement", memberInfo.getPersonalAchievement());
        if (memberInfo.getMemberImageId() != null) {
            update.set("memberImageId", memberInfo.getMemberImageId());
        }
        UpdateResult first = mongoTemplate.update(MemberInfo.class)
                .matching(query)
                .apply(update)
                .first();
        return 1;
    }

    @Override
    public UserInfo queryPassword(UserInfo userInfo) {
        Query query = Query.query(Criteria.where("_id").is(userInfo.getUserAccount()));
        UserInfo res = mongoTemplate.findOne(query, UserInfo.class);
        return res;
    }

    @Override
    public long updatePassword(UserInfo userInfo) {
        Query query = Query.query(Criteria.where("_id").is(userInfo.getUserAccount()));
        Update update = new Update();
        update.set("password",userInfo.getPassword());
        return mongoTemplate.updateFirst(query,update, UserInfo.class).getMatchedCount();
    }

    @Override
    public List<UserInfoVO> queryUserInfo(UserInfo userInfo) {
        Query query = Query.query(Criteria.where("_id").is(userInfo.getUserAccount()));
        List<UserInfoVO> list = mongoTemplate.find(query, UserInfoVO.class);
        return list;
    }

    @Override
    public void updateMemberShownStatus(MemberToShowVO memberToShowVO) {
        System.out.println(memberToShowVO);
        Query query = Query.query(Criteria.where("_id").is(memberToShowVO.getMemberId()));
        Update update = new Update();
        update.set("isShown", memberToShowVO.getIsShown());
        UpdateResult first = mongoTemplate.update(MemberInfo.class)
                .matching(query)
                .apply(update)
                .first();
        System.out.println(first);
    }

    @Override
    public void addTechStackInfo(TechStackInfo techStackInfo) {
        mongoTemplate.insert(techStackInfo);
        return;
    }

    @Override
    public void deleteTechStackInfo(List<String> listWithoutNulls) {
        Query query = Query.query(Criteria.where("_id").in(listWithoutNulls));
        List<TechStackInfo> allAndRemove = mongoTemplate.findAllAndRemove(query, TechStackInfo.class);
        allAndRemove.forEach(System.out::println);
    }

    @Override
    public void updateTechStackInfo(TechStackInfo techStackInfo) {
        Query query = Query.query(Criteria.where("_id").is(techStackInfo.getTechStackInfoId()));
        Update update = new Update();
        update.set("techStack", techStackInfo.getTechStack())
                .set("techStackIntroduction", techStackInfo.getTechStackIntroduction())
                .set("techStackWeight",techStackInfo.getTechStackWeight());
//        Update update = Update
//                .update("techStack", techStackInfo.getTechStack())
//                .set("techStackIntroduction", techStackInfo.getTechStackIntroduction())
//                .set("techStackWeight",techStackInfo.getTechStackweight());
        mongoTemplate.update(TechStackInfo.class)
                .matching(query)
                .apply(update)
                .first();
        return;
    }

    @Override
    public void updateArticle(String articleId, String articleContent){
        Query query = Query.query(Criteria.where("_id").is(articleId));
        Update update = new Update();
        update.set("content",articleContent);
        System.out.println(mongoTemplate.updateFirst(query, update, ArticleVO.class).getMatchedCount());
    }

    @Override
    public MemberInfo queryMemberById(String memberId) {
        Query query = new Query(Criteria.where("_id").is(memberId));
        MemberInfo one = mongoTemplate.findOne(query, MemberInfo.class);
        return one;
    }


}
